"""
FastAPI主应用 - 统一API网关
提供完整的HR智能分析服务接口
"""

from fastapi import FastAPI, HTTPException, BackgroundTasks, Depends, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from contextlib import asynccontextmanager
import asyncio
from typing import Dict, List, Any, Optional
from datetime import datetime
import uvicorn

from ...core.config import config
from ...core.interfaces import Task, TaskStatus
from ...agents.agent_manager import agent_manager
from ...lightrag_engine.rag_controller import RAGController
from .models import *
from .dependencies import create_tables
from .routes.auth import router as auth_router
from .routes.hr import router as hr_router
from .routes.candidate import router as candidate_router
from .routes.demo_hr import router as demo_hr_router
from .routes.demo_candidate import router as demo_candidate_router
from .routes.jh_routes import router as jh_router
from .routes.jh_chat import router as jh_chat_router
from .routes import analysis_router, system_router, data_router


@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    # 启动时初始化
    try:
        print("🚀 Initializing BoLe HR Platform...")
        
        # 创建数据库表
        create_tables()
        print("✅ Database tables created/updated!")
        
        # 初始化智能体管理器
        await agent_manager.initialize()
        
        print("✅ System initialized successfully!")
        yield
        
    except Exception as e:
        print(f"❌ Initialization failed: {e}")
        raise
    finally:
        # 关闭时清理
        print("🛑 Shutting down system...")
        await agent_manager.shutdown()


# 创建FastAPI应用
app = FastAPI(
    title="BoLe HR Platform API",
    description="智能HR多智能体平台 - 基于LightRAG的智能招聘解决方案",
    version="0.1.0",
    lifespan=lifespan
)

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 生产环境中应该限制具体域名
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由模块
app.include_router(auth_router, prefix="/api")
app.include_router(hr_router, prefix="/api")
app.include_router(candidate_router, prefix="/api")
app.include_router(jh_router, prefix="/api")  # JH子系统路由
app.include_router(jh_chat_router, prefix="/api")  # JH AI聊天路由
# 演示模式路由（无需认证）
app.include_router(demo_hr_router, prefix="/api")
app.include_router(demo_candidate_router, prefix="/api")
app.include_router(analysis_router)
app.include_router(system_router)
app.include_router(data_router)

# 核心功能测试路由
from .routes.core_test import router as core_test_router
app.include_router(core_test_router)


# ================================
# 健康检查和系统状态接口
# ================================

@app.get("/health", response_model=HealthResponse)
async def health_check():
    """健康检查接口"""
    try:
        health_status = await agent_manager.health_check()
        return HealthResponse(**health_status)
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail=f"Health check failed: {str(e)}"
        )


@app.get("/status", response_model=SystemStatusResponse)
async def get_system_status():
    """获取系统状态"""
    try:
        system_status = await agent_manager.get_system_status()
        return SystemStatusResponse(**system_status)
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get system status: {str(e)}"
        )


# ================================
# 核心分析接口 
# ================================

@app.post("/analyze/resume", response_model=AnalysisResponse)
async def analyze_resume(request: ResumeAnalysisRequest):
    """简历分析接口"""
    try:
        # 创建分析任务
        task = Task(
            id=f"resume_analysis_{datetime.now().timestamp()}",
            description=request.query,
            task_type="resume_analysis",
            metadata={
                "job_requirements": request.job_requirements,
                "analysis_depth": request.analysis_depth,
                "include_recommendations": request.include_recommendations
            }
        )
        
        # 执行任务
        orchestrator = agent_manager.get_orchestrator()
        if not orchestrator:
            raise HTTPException(
                status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
                detail="Orchestrator not available"
            )
        
        result_task = await orchestrator.orchestrate_task(task)
        
        # 构建响应
        if result_task.status == TaskStatus.COMPLETED:
            return AnalysisResponse(
                task_id=result_task.id,
                status="completed",
                result=result_task.result,
                processing_time=_calculate_processing_time(result_task),
                timestamp=datetime.now()
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                detail=f"Analysis failed: {result_task.result.get('error', 'Unknown error')}"
            )
            
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Resume analysis failed: {str(e)}"
        )


@app.post("/analyze/candidates/compare", response_model=ComparisonResponse)
async def compare_candidates(request: CandidateComparisonRequest):
    """候选人比较分析接口"""
    try:
        # 创建比较任务
        task = Task(
            id=f"candidate_comparison_{datetime.now().timestamp()}",
            description=f"比较分析候选人: {', '.join(request.candidate_queries)}",
            task_type="candidate_comparison",
            metadata={
                "candidate_queries": request.candidate_queries,
                "job_requirements": request.job_requirements,
                "comparison_criteria": request.comparison_criteria
            }
        )
        
        orchestrator = agent_manager.get_orchestrator()
        result_task = await orchestrator.orchestrate_task(task)
        
        if result_task.status == TaskStatus.COMPLETED:
            return ComparisonResponse(
                task_id=result_task.id,
                status="completed",
                comparison_result=result_task.result,
                candidates_analyzed=len(request.candidate_queries),
                processing_time=_calculate_processing_time(result_task),
                timestamp=datetime.now()
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                detail=f"Comparison failed: {result_task.result.get('error', 'Unknown error')}"
            )
            
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Candidate comparison failed: {str(e)}"
        )


@app.post("/analyze/background-check", response_model=BackgroundCheckResponse)
async def background_check(request: BackgroundCheckRequest):
    """背景核查接口"""
    try:
        task = Task(
            id=f"background_check_{datetime.now().timestamp()}",
            description=request.candidate_info,
            task_type="background_check",
            metadata={
                "verification_depth": request.verification_depth,
                "check_social_media": request.check_social_media,
                "verify_references": request.verify_references
            }
        )
        
        orchestrator = agent_manager.get_orchestrator()
        result_task = await orchestrator.orchestrate_task(task)
        
        if result_task.status == TaskStatus.COMPLETED:
            return BackgroundCheckResponse(
                task_id=result_task.id,
                status="completed",
                verification_result=result_task.result,
                risk_level=result_task.result.get("risk_assessment", {}).get("risk_level", "unknown"),
                processing_time=_calculate_processing_time(result_task),
                timestamp=datetime.now()
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                detail=f"Background check failed: {result_task.result.get('error', 'Unknown error')}"
            )
            
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Background check failed: {str(e)}"
        )


@app.post("/analyze/potential", response_model=PotentialAssessmentResponse)
async def assess_potential(request: PotentialAssessmentRequest):
    """潜力评估接口"""
    try:
        task = Task(
            id=f"potential_assessment_{datetime.now().timestamp()}",
            description=request.candidate_info,
            task_type="potential_assessment",
            metadata={
                "assessment_dimensions": request.assessment_dimensions,
                "prediction_timeframe": request.prediction_timeframe
            }
        )
        
        orchestrator = agent_manager.get_orchestrator()
        result_task = await orchestrator.orchestrate_task(task)
        
        if result_task.status == TaskStatus.COMPLETED:
            return PotentialAssessmentResponse(
                task_id=result_task.id,
                status="completed",
                assessment_result=result_task.result,
                potential_score=result_task.result.get("potential_score", {}).get("overall_potential", 0),
                processing_time=_calculate_processing_time(result_task),
                timestamp=datetime.now()
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                detail=f"Potential assessment failed: {result_task.result.get('error', 'Unknown error')}"
            )
            
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Potential assessment failed: {str(e)}"
        )


# ================================
# RAG查询接口
# ================================

@app.post("/query/rag", response_model=RAGQueryResponse)
async def rag_query(request: RAGQueryRequest):
    """RAG查询接口"""
    try:
        # 获取RAG控制器
        rag_controller = await agent_manager.orchestrator.rag_controller
        if not rag_controller:
            raise HTTPException(
                status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
                detail="RAG controller not available"
            )
        
        # 执行RAG查询
        result = await rag_controller.process_query(
            query=request.query,
            retrieval_modes=request.retrieval_modes,
            top_k=request.top_k,
            rerank_top_k=request.rerank_top_k,
            template_name=request.template_name,
            return_intermediate=request.return_intermediate
        )
        
        return RAGQueryResponse(
            query=request.query,
            answer=result.get("answer", ""),
            processing_time=result.get("processing_time", {}),
            search_results=result.get("search_results", []) if request.return_intermediate else None,
            reranked_results=result.get("reranked_results", []) if request.return_intermediate else None,
            timestamp=datetime.now()
        )
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"RAG query failed: {str(e)}"
        )


# ================================
# 数据管理接口
# ================================

@app.post("/data/upload", response_model=DataUploadResponse)
async def upload_data(request: DataUploadRequest, background_tasks: BackgroundTasks):
    """数据上传接口"""
    try:
        # 获取数据灌入管道
        orchestrator = agent_manager.get_orchestrator()
        ingestion_pipeline = orchestrator.rag_controller.ingestion_pipeline
        
        if request.data_type == "file_path":
            # 处理文件路径
            background_tasks.add_task(
                ingestion_pipeline.process_file,
                request.data_content
            )
        elif request.data_type == "directory":
            # 处理目录
            background_tasks.add_task(
                ingestion_pipeline.process_directory,
                request.data_content
            )
        elif request.data_type == "huggingface_dataset":
            # 处理HuggingFace数据集
            background_tasks.add_task(
                ingestion_pipeline.process_huggingface_dataset,
                request.data_content
            )
        
        return DataUploadResponse(
            upload_id=f"upload_{datetime.now().timestamp()}",
            status="processing",
            data_type=request.data_type,
            message="Data upload started, processing in background",
            timestamp=datetime.now()
        )
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Data upload failed: {str(e)}"
        )


@app.get("/data/stats", response_model=DataStatsResponse)
async def get_data_stats():
    """获取数据统计信息"""
    try:
        orchestrator = agent_manager.get_orchestrator()
        pipeline_stats = await orchestrator.rag_controller.ingestion_pipeline.get_pipeline_stats()
        
        return DataStatsResponse(
            pipeline_stats=pipeline_stats,
            timestamp=datetime.now()
        )
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=f"Failed to get data stats: {str(e)}"
        )


# ================================
# 任务管理接口
# ================================

@app.get("/tasks/{task_id}", response_model=TaskStatusResponse)
async def get_task_status(task_id: str):
    """获取任务状态"""
    try:
        orchestrator = agent_manager.get_orchestrator()
        
        # 检查运行中的任务
        if task_id in orchestrator.running_tasks:
            task = orchestrator.running_tasks[task_id]
            return TaskStatusResponse(
                task_id=task.id,
                status=task.status.value,
                description=task.description,
                result=task.result,
                metadata=task.metadata,
                timestamp=datetime.now()
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Task {task_id} not found"
            )
            
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to get task status: {str(e)}"
        )


@app.delete("/tasks/{task_id}")
async def cancel_task(task_id: str):
    """取消任务"""
    try:
        orchestrator = agent_manager.get_orchestrator()
        success = await orchestrator.cancel_task(task_id)
        
        if success:
            return {"message": f"Task {task_id} cancelled successfully"}
        else:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Task {task_id} not found or cannot be cancelled"
            )
            
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to cancel task: {str(e)}"
        )


# ================================
# 批量处理接口
# ================================

@app.post("/batch/analyze", response_model=BatchAnalysisResponse)
async def batch_analyze(request: BatchAnalysisRequest, background_tasks: BackgroundTasks):
    """批量分析接口"""
    try:
        # 创建批量任务
        batch_id = f"batch_{datetime.now().timestamp()}"
        
        # 在后台处理批量任务
        background_tasks.add_task(
            _process_batch_analysis,
            batch_id,
            request.queries,
            request.analysis_type,
            request.batch_options
        )
        
        return BatchAnalysisResponse(
            batch_id=batch_id,
            status="processing",
            total_queries=len(request.queries),
            message="Batch analysis started, processing in background",
            timestamp=datetime.now()
        )
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Batch analysis failed: {str(e)}"
        )


# ================================
# 辅助函数
# ================================

def _calculate_processing_time(task: Task) -> Dict[str, float]:
    """计算任务处理时间"""
    if not task.metadata:
        return {"total": 0.0}
    
    started_at = task.metadata.get("started_at")
    completed_at = task.metadata.get("completed_at") or task.metadata.get("failed_at")
    
    if started_at and completed_at:
        start_time = datetime.fromisoformat(started_at)
        end_time = datetime.fromisoformat(completed_at)
        total_time = (end_time - start_time).total_seconds()
        return {"total": total_time}
    
    return {"total": 0.0}


async def _process_batch_analysis(
    batch_id: str,
    queries: List[str],
    analysis_type: str,
    batch_options: Dict[str, Any]
):
    """处理批量分析（后台任务）"""
    try:
        orchestrator = agent_manager.get_orchestrator()
        
        # 创建批量任务
        tasks = []
        for i, query in enumerate(queries):
            task = Task(
                id=f"{batch_id}_query_{i}",
                description=query,
                task_type=analysis_type,
                metadata=batch_options
            )
            tasks.append(task)
        
        # 并行执行任务（控制并发数）
        semaphore = asyncio.Semaphore(5)
        
        async def process_single_task(task):
            async with semaphore:
                return await orchestrator.orchestrate_task(task)
        
        results = await asyncio.gather(*[process_single_task(task) for task in tasks])
        
        # 这里可以将结果存储到数据库或缓存中
        # 暂时只打印日志
        print(f"Batch {batch_id} completed with {len(results)} results")
        
    except Exception as e:
        print(f"Batch {batch_id} failed: {str(e)}")


# ================================
# 异常处理
# ================================

@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
    """HTTP异常处理器"""
    return JSONResponse(
        status_code=exc.status_code,
        content={
            "error": exc.detail,
            "status_code": exc.status_code,
            "timestamp": datetime.now().isoformat()
        }
    )


@app.exception_handler(Exception)
async def general_exception_handler(request, exc):
    """通用异常处理器"""
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "error": "Internal server error",
            "detail": str(exc),
            "timestamp": datetime.now().isoformat()
        }
    )


# ================================
# 开发环境启动
# ================================

if __name__ == "__main__":
    # 获取配置
    api_config = config.get("services.api", {})
    host = api_config.get("host", "0.0.0.0")
    port = api_config.get("port", 8000)
    reload = api_config.get("reload", True)
    
    uvicorn.run(
        "main:app",
        host=host,
        port=port,
        reload=reload,
        log_level="info"
    )